package com.mikhailenko.transportMVC.utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.stereotype.Component;

import com.mikhailenko.transportMVC.model.Table;
import com.mikhailenko.transportMVC.model.TableForm;

@Component
public class Nmai {

	 
	public double[][] getRowSum(List<List<String>> table){
		int countOfTerms = table.get(0).get(0).split(",").length;
		double[][] rowSums = new double[table.size()][countOfTerms];
		
		for (int i = 0; i < table.size(); i++){
			
			double[] sums = new double[countOfTerms]; 
			
			for (int j = 0; j < table.get(i).size(); j++){
				
				String[] triangleNumber = table.get(i).get(j).split(","); // TODO: make option to choose separator
				
				for (int k = 0; k < countOfTerms; k++){
					sums[k] += Convertor.getDecimalFromFraction(triangleNumber[k]);
				}
			}
			
			rowSums[i] = sums;
		}
		return rowSums;
	}
	
	public double[] getDeterminedVectorInverce(List<List<String>>  table){
		int countOfTerms = table.get(0).get(0).split(",").length;
		double[] determinedVector = new double[countOfTerms]; 
		
		double[] sums = new double[countOfTerms]; 
		
		for (int i = 0; i < table.size(); i++){
			for (int j = 0; j < table.get(0).size(); j++){
				String[] fuzzyNumber = table.get(i).get(j).split(",");
				for (int k = 0; k < countOfTerms; k++){
					sums[k] += Convertor.getDecimalFromFraction(fuzzyNumber[k]);
				}
			}
		}
		
		int j = countOfTerms - 1;
		for (int i = 0; i < countOfTerms; i++){
			determinedVector[i] = 1 / sums[j--];
		}
		
		return determinedVector;
	}
	
	public double[][] getFuzzyMultiplication(double[][] rowSum, double[] detVector){
		double[][] multiplication =  new double[rowSum.length][detVector.length];
		
		for (int i = 0; i < rowSum.length; i++){
			double [] mul = new double[detVector.length];
			for (int j = 0; j < detVector.length; j++){
				mul[j] = rowSum[i][j] * detVector[j];
			}
			multiplication[i] = mul;
		}
		return multiplication;
	}
	
	public double[] getPriorityVector(double[][] fuzzyMultiplication){
		double[] priorityVector = new double[fuzzyMultiplication.length];
		
		for (int i = 0; i < fuzzyMultiplication.length; i++){
			List<Double> tempResult = new ArrayList<Double>();
			for (int j = 0; j < fuzzyMultiplication.length; j++){
				if(i != j){
					tempResult.add(compareToTriangle(fuzzyMultiplication[i], fuzzyMultiplication[j]));
				}
			}
			priorityVector[i] = Collections.min(tempResult);
		}
		
		return normalizeVector(priorityVector);
	}
	
	public double compareToTriangle(double[] one, double[] two){
		if ( one[1] >= two[1]){
			return 1;
		} else if ( two[0] >= one[2]){
			return 0;
		} else{
			return (two[0] - one[2])/((one[1] - one[2]) - (two[1] - two[0]));
		}
	}
	
	
	
	public Table getResultTable(TableForm tableForm){
	    List<String> coeficientsForCriteria = tableForm.getTableList().get(0).getPriorityVector();
	    
	    Table result = new Table();
	    
	    List<List<String>> resultTable = new ArrayList<List<String>>();
	    
	    
	    for (int i = 1; i < tableForm.getTableList().size(); i++){
	        resultTable.add(tableForm.getTableList().get(i).getPriorityVector());
	    }
	    
	    String[][] temp = new String[resultTable.get(0).size()][resultTable.size()];
	    for (int i = 0; i < resultTable.size(); i++){
	        for (int j = 0; j < resultTable.get(i).size(); j++){
	            temp[j][i] = resultTable.get(i).get(j);
	        }
	    }
	    
	    resultTable = Convertor.masToList(temp);
	    
	    double[][] multiply = new double[resultTable.size()][resultTable.get(0).size()];
	    
	    for (int i = 0; i < resultTable.size(); i++){
	        for (int j = 0; j < resultTable.get(i).size(); j++){
	            double priority = Double.valueOf(resultTable.get(i).get(j));
	            double coef  = Double.valueOf(coeficientsForCriteria.get(j));
	            multiply[i][j] = priority * coef;
	        }
	    }

	    List<String> priorityVector = new ArrayList<String>();
	    priorityVector = Convertor.masToList(findPriorityResult(multiply));
	    
	    result.setTable(resultTable);
	    result.setPriorityVector(priorityVector);
	    return result;
	}
	
	private double[] findPriorityResult(double[][] mas){
	    double[] result = new double[mas.length];
	    
	    
	    for (int i = 0; i < mas.length; i++){
	        double sum = 0;
	        for (int j = 0; j < mas[i].length; j++){
	            sum += mas[i][j]; 
	        }
	        result[i] = sum;
	    }
	    
	    return normalizeVector(result);
	}
	
	private double findMasSum(double[] mas){
	    double totalResult = 0;
	    
	    for (int i = 0; i < mas.length; i++){
	        totalResult += mas[i];
	    }
	    
	    return totalResult;
	}
	
	private double[] normalizeVector(double[] mas){
	    double[] result = new double[mas.length];
	    double totalSum = findMasSum(mas);
        
        for (int i = 0; i < result.length; i++){
            result[i] = mas[i] / totalSum;
        }
        
        return result;
	}
}
